# [十一]Spring AOP - 代理入口类

# 是否生成代理

当一个bean 实例化完成后,会判断该 bean 是否生成代理: AOP 的入口,找到doCreateBean()方法

所在类 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		// AOP 的入口方法
		exposedObject = initializeBean(beanName, exposedObject, mbd);
}

进入initializeBean() 方法

所在类 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
Object wrappedBean = bean;
		
		if (mbd == null || !mbd.isSynthetic()) {
			// AOP入口的具体生产 代理实例方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		
}
}

知识点

applyBeanPostProcessorsAfterInitialization() 方法是一个 BeanPostProcessor 接口的运用,initializeBean 方法我们都知道是一个bean 实例化完成后做的操作,而这个代理实例生成也是在bean 实例化完成后做的操作。

进入applyBeanPostProcessorsAfterInitialization()方法

所在类 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory

/**
 * TODO: 当bean 实例化完成后的 代理包装
 */
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

进入BeanPostProcessor类的postProcessAfterInitialization()方法

找到实现类AbstractAutoProxyCreatorpostProcessAfterInitialization()方法

所在类 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

/**
 * TODO: 验证
 */
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

进入wrapIfNecessary()方法

所在类 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

/**
 * TODO: 创建当前bean的代理,核心方法
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 创建当前bean的代理,如果这个bean有advice的话,重点看,重要程度5
		// 得到所有的可用于拦截当前 bean 的 advisor、advice、interceptor
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 如果有切面,则生成该bean的代理
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 把被代理对象bean实例封装到SingletonTargetSource对象中
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

进入getAdvicesAndAdvisorsForBean()方法,继续进入findEligibleAdvisors()方法

所在类 org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator

/**
 * TODO:查找@Aspectj注解的类,核心方法
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 找到候选的切面,其实就是一个寻找有@Aspectj注解的过程,
    	// 把工程中所有有这个注解的类封装成Advisor返回
		List<Advisor> candidateAdvisors = findCandidateAdvisors();

		// 判断候选的切面是否作用在当前beanClass上面,就是一个匹配过程。
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			//对有@Order@Priority进行排序
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

知识点

如何查找当前bean 的切面

  • 1、从Spring中查找所有的切面

    • ①、首先找到所有的BeanDefinition 对象对应的 beanName,反射拿到对应的 Class 对象,判断该类上面是否有@Aspect 注解,有则是我们要找的;
    • ② 、 然后循环该Class 里面的除了@PointCut 注解的方法,找到方法上的Around.class,Before.class, After.class,AfterReturning.class,AfterThrowing.class注解,并且把注解里面的信息,比如表达式、argNames、注解类型等信息封装成对象AspectJAnnotation;
    • ③ 、接着创建pointCut 对象,把注解对象中的表达式设置到 pointCut 对象中;
    • ④、最后就是创建 Advice 对象,根据不同的注解类型创建出不同的Advice对象,对象如 下 :AspectJAroundAdvice,AspectJAfterAdvice, AspectJAfterThrowingAdvice,AspectJMethodBeforeAdvice, AspectJAfterReturningAdvice 最终把注解对应的Advice对象和pointCut对象封装成Advisor 对象。
  • 2、找到拦截当前bean的切面

    • 从收集到的所有切面中,每一个切面都会有pointCut来进行模块匹配,其实这个过程就是一个匹配过程,看看pointCut表达式中的内容是否包含了当前 bean,如果包含了,那么这个 bean 就有切面,就会生成代理。

# 代理类的调用

		//创建当前bean的代理,如果这个bean有advice的话,重点看,重要程度5
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		//如果有切面,则生成该bean的代理
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//把被代理对象bean实例封装到SingletonTargetSource对象中
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;

getAdvicesAndAdvisorsForBean()方法拦截到有advice的类,如果返回的Object[] specificInterceptors数组不为空,最终会执行到createProxy() ,这个方法就会生成 bean的代理实例。

进入createProxy 方法

所在类 org.springframework.aop.framework.AbstractAutoProxyCreator

/**
 * TODO : 创建代理实例
 * @param beanClass 类对象
 * @param beanName bean 名字
 * @param specificInterceptors 拦截到的所有的 advisors
 * @param targetSource 具体类实现的信息(被代理实例)
 * @return
 */
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}
		//创建代理工厂实例
		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				// proxyTargetClass 是否对类进行代理,而不是对接口进行代理,
                // 设置为true时,使用CGLib代理。
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				// 1. 有接口的,循环调用:proxyFactory.addInterface(ifc);
				// 2. 没有接口的,调用:proxyFactory.setProxyTargetClass(true);
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
 		// 把 advice 类型的增强包装成 advisor 切面
		// 返回匹配了当前 bean 的 advisors 数组
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);
		// 用来控制代理工厂被配置后,是否还允许修改代理的配置,默认为false
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
		// 获取代理实例
		return proxyFactory.getProxy(getProxyClassLoader());
	}

进入buildAdvisors 方法

所在类 org.springframework.aop.framework.AbstractAutoProxyCreator

/**
 * TODO : 包装成 advisor 切面的过程
 */
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
		// 自定义 MethodInterceptor 拿到 AnnotationAwareAspectJAutoProxyCreator
     	// 对象调用 setInterceptorNames方法
		Advisor[] commonInterceptors = resolveInterceptorNames();
		List<Object> allInterceptors = new ArrayList<>();
		if (specificInterceptors != null) {
			allInterceptors.addAll(Arrays.asList(specificInterceptors));
			if (commonInterceptors.length > 0) {
				if (this.applyCommonInterceptorsFirst) {
					allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
				}
				else {
					allInterceptors.addAll(Arrays.asList(commonInterceptors));
				}
			}
		}
		if (logger.isTraceEnabled()) {
			int nrOfCommonInterceptors = commonInterceptors.length;
			int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
			logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
					" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
		}

		Advisor[] advisors = new Advisor[allInterceptors.size()];
		for (int i = 0; i < allInterceptors.size(); i++) {
			// 对自定义的 advice要进行包装,把 advice包装成 advisor对象,切面对象
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}

执行完buildAdvisors 方法,返回匹配了当前 bean 的 advisors 数组

继续执行createProxy方法,进入getProxy()方法

所在类 org.springframework.aop.framework.ProxyFactory

public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

进入createAopProxy()方法

所在类 org.springframework.aop.framework.ProxyCreatorSupport

protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		// 创建一个 AopProxy 的实例
		return getAopProxyFactory().createAopProxy(this);
	}

创建createAopProxy()方法 之前,需要拿到一个AopProxyFactory 实例

进入getAopProxyFactory()方法

所在类 org.springframework.aop.framework.ProxyCreatorSupport

public class ProxyCreatorSupport extends AdvisedSupport {

private AopProxyFactory aopProxyFactory;

public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}

public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}
}

很明显,拿到的this.aopProxyFactory的值,来自构造方法new DefaultAopProxyFactory()

进入DefaultAopProxyFactory类的createAopProxy()方法

所在类 org.springframework.aop.framework.DefaultAopProxyFactory

/**
* TODO : 创建 AopProxy 代理实例
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			// 如果要代理的类本身就是接口,创建一个新的 JDK代理实例,多例模式
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			// 否则使用 Cglib 代理
			// ObjenesisCglibAopProxy 在Spring4.0 就有了
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			// 如果有接口,创建一个新的 JDK代理实例,多例模式
			return new JdkDynamicAopProxy(config);
		}
	}

知识点

  • 如果被代理的目标类实现了一个或多个自定义的接口,那么就会使用 JDK 动态代理;
  • 如果被代理的目标类没有实现任何接口,会使用 CGLIB 实现代理;
  • 如果设置了proxyTargetClass="true",那么都会使用 CGLIB生成代理;

总结: JDK 动态代理基于接口,所以只有接口中的方法会被增强(因为代理类已经继承了Proxy),而 CGLIB 基于类继承,如果目标类中的方法使用了finalprivate 关键字来修饰,是不能被增强的。

当被代理的目标类是基于JDK的动态代理,进入JdkDynamicAopProxy()的构造方法

所在类 org.springframework.aop.framework.JdkDynamicAopProxy

// 代理工厂对象(保存这个AOP代理所有的配置信息  包括所有的增强器等等)
private final AdvisedSupport advised;
//......省略无关代码
/**
 * TODO : 根据参数中指定的配置(config)构造一个新的JdkDynamicAopProxy
 */
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		// 校验:必须有至少一个增强器和目标实例
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		this.advised = config;
	}

到此,已经创建好了AopProxy,返回到最初的getProxy()方法

public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

拿到了AopProxy,接着可以调用到了getProxy()方法

进入getProxy()最核心的方法

所在类 org.springframework.aop.framework.JdkDynamicAopProxy

/**
 * TODO : 创建JDK动态代理实例
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
	if (logger.isTraceEnabled()) {
		logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
	}
	/**
	 *  TODO : 查找接口(advised 是代理工厂对象)
	 *  我们看到最终代理的接口就是这里返回的所有接口们(除了我们自己的接口,还有Spring默认的一些接口)
	 *  大致过程如下:
	 *   1、获取目标对象自己实现的接口(最终肯定都会被代理的)
	 * 	 2、是否添加`SpringProxy`这个接口:目标对象实现对就不添加了,没实现过就添加true
	 * 	 3、是否新增`Adviced`接口,注意不是Advice通知接口。 实现过就不实现了,
	 * 	    没实现过并且advised.isOpaque()=false就添加(默认是会添加的)
	 * 	 4、是否新增DecoratingProxy接口。传入的参数decoratingProxy为true,
	 * 	    并且没实现过就添加(显然这里,首次进来是会添加的)
	 * 	 5、代理类的接口一共是目标对象的接口+上面三个接口SpringProxy、Advised、DecoratingProxy
	 *      (SpringProxy是个标记接口而已,其余的接口都有对应的方法的)
	 * 	 备注:DecoratingProxy 这个接口是 Spring4.3后才提供
	 */

	Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
	findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
	// 第三个参数传的 this,处理器就是当前类(实现了 InvocationHandler 接口)
	return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

拿到代理对象调用,以 jdk 动态代理为例(Cglib 是一样的调用逻辑)。 当发生代理对象调用时,会调用到实现了 invocationHandler 接口的类,这个类就JdkDynamicAopProxy,然后会调用到该类的 invoke 方法。

进入invoke()方法

所在类 org.springframework.aop.framework.JdkDynamicAopProxy

说明

JdkDynamicAopProxy 本身实现了InvocationHandler 接口和AopProxy 接口所以 JdkDynamicAopProxy实现的InvocationHandler.invoker()方法就是Proxy 对象回调的方法。实现的AopProxy.getProxy()方法就是通过JDK动态代理生成的代理对象,传递的InvocationHandler 对象就是 JdkDynamicAopProxy 自身。这就是动态代理了,切面的业务就是在 invoke()方法中体现的。具体业务在源码中体现。

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	MethodInvocation invocation;
	Object oldProxy = null;
	boolean setProxyContext = false;
	// 从代理工厂中拿到 TargetSource 对象,该对象包装了被代理实例 bean
	// 因为 InvocationHandler 持久的就是 targetSource,最终通过 getTarget 拿到目标对象
	TargetSource targetSource = this.advised.targetSource;
	Object target = null;

	try {
		// 被代理对象的 equals方法和 hashCode方法是不能被代理的,不会走切面
		// 所以此处做了处理 :
		// equalsDefined为false(表示自己没有定义过 equals方法)  那就交给代理去比较
		// hashCode同理,只要你自己没有实现过此方法,那就交给代理类处理
		// 需要注意的是:这里统一指的是,如果接口上有此方法,但是你自己并没有实现 equals和 hashCode
        //  方法,那就走AOP这里的实现
		// 如过接口上没有定义此方法,只是实现类里自己 @Override了 HashCode,那是无效的,
        //  就不做特殊处理
		if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
			// The target does not implement the equals(Object) method itself.
			return equals(args[0]);
		}
		else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
			// The target does not implement the hashCode() method itself.
			return hashCode();
		}
		// DecoratingProxy的方法和Advised接口的方法都是最终调用了config,也就是this.advised去执行的
		else if (method.getDeclaringClass() == DecoratingProxy.class) {

			return AopProxyUtils.ultimateTargetClass(this.advised);
		}
		else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
				method.getDeclaringClass().isAssignableFrom(Advised.class)) {

			return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
		}
		// 这个是最终该方法的返回值
		Object retVal;
		// 是否暴露代理对象,默认false可配置为true,如果暴露就意味着允许在线程内共享代理对象,
		// 注意这是在线程内,也就是说同一线程的任意地方都能通过 AopContext 获取该代理对象,
		// 这里缓存一份代理对象在 oldProxy
		if (this.advised.exposeProxy) {
			oldProxy = AopContext.setCurrentProxy(proxy);
			setProxyContext = true;
		}
		// 通过目标源获取目标对象,这个 target 就是目标对象(被代理实例)
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);

		// 获取作用在这个方法上的所有拦截器链
		//会根据切点表达式去匹配这个方法。因此其实每个方法都会进入这里,只是有很多方法的拦截器链是空的
		//从代理工厂中拿过滤器链 Object是一个 MethodInterceptor类型的对象,其实就是一个advice对象
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
		// 如果该方法没有执行链,则说明这个方法不需要被拦截,则直接反射调用
		if (chain.isEmpty()) {
			// 若拦截器为空,那就直接调用目标方法了
			// 对参数进行适配:主要处理一些数组类型的参数,看是表示一个参数还是表示多个参数
            //  (可变参数最终到此都是数组类型,所以最好是需要一次适配)
			Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			// 直接通过反射调用目标方法
			retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
		}
		else {
			// 创建一个 invocation ,此处为 ReflectiveMethodInvocation  最终是通过它,
            // 去执行前置加强、后置加强等逻辑
			invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
			// 此处会执行所有的拦截器链  交给Spring AOP的 MethodInvocation 去处理。
			// 其实现还是 Spring 的 ReflectiveMethodInvocation
			retVal = invocation.proceed();
		}

		// Massage return value if necessary.
		// 获取返回值的类型
		Class<?> returnType = method.getReturnType();
		// 判断条件,如果返回值不为空,且为目标对象的话,就直接将目标对象赋值给 retVal
		if (retVal != null && retVal == target &&
				returnType != Object.class && returnType.isInstance(proxy) &&
				!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
			retVal = proxy;
		}
		// 返回 null,并且还不是 Void类型,抛出异常
		else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
			throw new AopInvocationException(
					"Null return value from advice does not match primitive return type for: " + method);
		}
		return retVal;
	}
	finally {
		if (target != null && !targetSource.isStatic()) {
			// Must have come from TargetSource.
			// 释放目标对象(被代理实例)
			targetSource.releaseTarget(target);
		}
		if (setProxyContext) {
			// Restore old proxy.
			// 把老的代理对象重新 set进去
			AopContext.setCurrentProxy(oldProxy);
		}
	}
	}

知识点

  • 除了实现类里自己写的方法(接口上没有的),其余方法统一都会进入代理得invoke()方法里面。只是invoke上做了很多特殊处理,比如DecoratingProxyAdvised等等的方法,都是直接执行了。
  • object的方法中,被代理对象的 equals方法和 hashCode方法是不能被代理的,不会被增强,但是toString()方法会被增强(不确定AdvisedSupport#methodCache这个字段事什么时候把toString()方法缓存上的,打断点都没跟踪上)
  • 生成出来的代理对象,Spring默认都给你实现了接口:SpringProxy、DecoratingProxy、Advised

# 创建代理的过程

  • 1、创建代理工厂对象 ProxyFactory
  • 2、切面对象重新包装,会把自定义的 MethodInterceptor 类型的类包装成 Advisor 切面类并加入到代理工厂中
  • 3、根据proxyTargetClass 参数和是否实现接口来判断是采用 jdk 代理还是cglib 代理
  • 4、创建代理对象,并且把代理工厂对象传递到 jdk 和 cglib 中,注意这里的代理对象和 jdk 类和 cglib 类是一一对应的。

# AOP问题汇总

问题一

实际生成的动态代理在哪里?

参考答案

生成的动态代理($Proxy0)是在JVM内存中的,一般情况是,先把java文件编译成class文件,然后类加载器加载这个class字节码文件,从而让JVM可以生成这个类的对象。但动态代理是,在内存中生成这些字节码,然后再正常地加载字节码,生成对象。

问题二

一个类中的方法如果有代理实例,那么这个代理实例会被IOC容器管理吗?

参考答案

问题三

AOP 拦截器调用如何实现的?

参考答案

如果是JDK实现的代理对象就会通过InvocationHandler 来完成拦截器回调,如果是CGLIB 就通过DynamicAdvisedInterceptor 来完成回调。

扩展阅读

通过AopProxy 对象封装target 目标对象之后,ProxyFactoryBean方法得到的对象已经是一个AopProxy代理对象了,在ProxyFactoryBean 中配置的target目标对象不会让应用直接调用其方法的实现,对target目标对象的方法调用会被AopProxy代理对象拦截,对于不同的AopProxy代理对象生成方式,会使用不同的拦截回调入口。对于 JDK的AopProxy代理对象,使用的是InvocationHander的invoker 回调入口。对于CGLIB的AopProxy代理对象,使用的是设置好的callbak 回调,在这里callback回调中,对于AOP的实现是通过DynamicAdvisedInterceptor 来完成的,DynamicAdvisedInterceptor 的回调入口是 intercept 方法。

问题四

Aspect 注解的类搜集方法的时候,为什么只循环没有@Pointcut 注解的方法?

参考答案

因为@Pointcut 只是切点表达式,不是通知方法

问题五

为什么依赖注入到三级缓存的是代理实例,而不是当前bean实例本身?

参考答案

因为Spring遵循了开闭原则,对修改关闭,对扩展开发,由于很多时候我们并不需要bean实例本身,而是需要修改后的实例,这样通过获取代理对象实例,可以更好的执行业务逻辑。

问题六

为什么实例化之前自定义代理保存到了三级缓存,拿到的却是bean实例本身?

参考答案

问题七

如何自定义一个拦截器链,添加到现在有的连接器链中?

参考答案

实现MethodInterceptor接口